package evolutionaryLoop;

import java.io.File;
import java.util.Calendar;
import java.util.GregorianCalendar;

import statistics.WriteStatistics;
import evolutionaryLoop.selectionMechanisme.SelectionMechanism;
import evolutionaryLoop.selectionProtocol.SelectionProtocol;
import fitnessFunctions.FitnessFunction;

public class EvolutionaryParameters {
	
	private int numberOfIterations; 
	private int populationSize; 
	private int numOfChildenToBeGenerated;
	private double culling = 0; 

	private int elitims; 
	private double mutationRate; 
	private double crossoverRate; 
	private int numOfCrossoverPoints; 
	private SelectionProtocol adultSelectionProtocol;
	private SelectionMechanism parenetSelectionMechanism;
	private FitnessFunction fitnessFunction; 
	
	private boolean viewMap;
	private long timePerFrame = 200; 
	
	private WriteStatistics writeStatistics; 
	
//	public static enum AdultSelectionProtocol{
//		fullGenerationReplacement,
//		overProduction, //best fitness
//		generatonMixing; //best fitness 
//	}
//	
//	public static enum ScalingMechanism{
//		fitness, 
//		sigma, 
//		rank, 
//		boltzmann, 
//		basic; 
//	}
//	public static enum SelectionMechanism{
//		rouletWheel, 
//		turnament; 
//	}

	public boolean isViewMap() {
		return viewMap;
	}
	public void setViewMap(boolean viewMap) {
		this.viewMap = viewMap;
	}
	
	public int getPopulationSize() {
		return populationSize;
	}

	public void setPopulationSize(int populationSize) {
		this.populationSize = populationSize;
	}

	public int getNumOfChildenToBeGenerated() {
		//TODO
		return numOfChildenToBeGenerated;
	}
	
	public void setNumOfChildenToBeGenerated(int numOfChildenToBeGenerated) {
		this.numOfChildenToBeGenerated = numOfChildenToBeGenerated;
	}

	public int getElitism() {
		return elitims;
	}

	public void setElitims(int elitims) {
		this.elitims = elitims;
	}

	public double getMutationRate() {
		return mutationRate;
	}

	public void setMutationRate(double bitwiseMutationRate) {
		this.mutationRate = bitwiseMutationRate;
	}

	public double getCrossoverRate() {
		return crossoverRate;
	}

	public void setCrossoverRate(double probabilityOfCrossover) {
		this.crossoverRate = probabilityOfCrossover;
	}

	public int getCrossoverPoints() {
		return numOfCrossoverPoints;
	}

	public void setCrossoverPoints(int numOfCrossoverPoints) {
		this.numOfCrossoverPoints = numOfCrossoverPoints;
	}

	public SelectionProtocol getAdultSelectionProtocol() {
		return adultSelectionProtocol;
	}

	public void setAdultSelectionProtocol(
			SelectionProtocol adultSelectionProtocol) {
		this.adultSelectionProtocol = adultSelectionProtocol;
	}

	public SelectionMechanism getParenetSelectionMechanism() {
		return parenetSelectionMechanism;
	}

	public void setParenetSelectionMechanism(
			SelectionMechanism parenetSelectionMechanism) {
		this.parenetSelectionMechanism = parenetSelectionMechanism;
	}

	public int getNumberOfIterations() {
		return numberOfIterations;
	}

	public void setMaxNumberOfIterations(int numberOfIterations) {
		this.numberOfIterations = numberOfIterations;
	}
	
	public int getIterationsAndDecrement(){
		return numberOfIterations--;
	}

	public double getCulling() {
		return culling;
	}
	
	public void setCulling(double d){
		culling = d; 
	}

	public FitnessFunction getFitnessFunction() {
		return fitnessFunction;
	}

	public void setFitnessFunction(FitnessFunction fitnessFunction) {
		this.fitnessFunction = fitnessFunction;
	}

	public WriteStatistics getWriteStatistics() {
		return writeStatistics;
	}

	public void setWriteStatistics(String name) {
		String pathVariable = "";
		pathVariable += name; 
		pathVariable += getDateStamp(); 
		pathVariable += ".csv"; 
		this.writeStatistics = new WriteStatistics(new File(pathVariable));
	}

	private String getDateStamp() {
		Calendar calender = GregorianCalendar.getInstance(); 
		int second = calender.get(calender.SECOND); 
		int minute = calender.get(calender.MINUTE);
		int hour = calender.get(calender.HOUR_OF_DAY);
		int date = calender.get(calender.DAY_OF_MONTH); 
		int month = calender.get(calender.MONTH) + 1; 
		int year = calender.get(calender.YEAR); 
		
		String theString = "  "; 
		theString += year + "_"; 
		theString += month + "_"; 
		theString += date + "   "; 
		theString += hour + "_"; 
		theString += minute + "_"; 
		theString += second; 
		
		return theString;
	}
	
	public String toString(){
		String theString = ""; 
		theString += ("Settings: ");
		theString += ("\nMutation rate: " + getMutationRate());
		theString += ("\nCrossover rate: " + getCrossoverRate());
		theString += ("\nParent selection mechanism: " + getParenetSelectionMechanism()); 
		theString += ("\nGeneration mixing: " + getAdultSelectionProtocol());
		theString += ("\nFitness function: " + getFitnessFunction());
		theString += "\n"; 
		return theString; 
	}
	public long getTimePerFrame() {
		return timePerFrame;
	}
	public void setTimePerFrame(long timePerFrame) {
		this.timePerFrame = timePerFrame;
	}
	public int getMaxNumberOfIterations() {
		return numberOfIterations;
	}

//	public SelectionMechanism getSelectionMechanisme() {
//		//  Auto-generated method stub
//		return null;
//	}
	
}
